#include "dialog.h"

namespace  IAlib
{

Dialog::Dialog()
{
    m_name = "";
    m_root = NULL;
}

Dialog::Dialog(const QString &dialog_name)
{
    m_name = dialog_name;
    m_root = NULL;
}

Dialog::Dialog(const Dialog &dialog)
{
    m_name = dialog.getName();
    if (dialog.m_root != NULL)
    {
        Phrase * phrase = new Phrase(*dialog.m_root);
        m_root = phrase;
    }
}

Dialog::~Dialog()
{
    if (m_root != NULL)
    {
        delete(m_root);
    }
}

bool Dialog::addPhrase(Phrase *phrase, QString id_parent)
{
    Phrase * parent_phrase = findPhrase(id_parent);
    if (parent_phrase != NULL && findPhrase(phrase->getId()) == NULL)
    {
        phrase->setParent(parent_phrase);
        parent_phrase->addChild(phrase);
        return true;
    }
    else
    {
        return false;
    }
}

QList<Phrase*> Dialog::getAllPhrase()
{
    QList<Phrase*> list;
    if (m_root != NULL)
    {
		list.append(m_root);
        m_root->getAllPhrase(list);
    }
    return list;
}

Phrase * Dialog::findPhrase(const QString &id)
{
    QList<Phrase*> list = getAllPhrase();
    for (int i = 0; i < list.size(); i++)
    {
        if (list[i]->getId() == id)
        {
            return list[i];
        }
    }
    return NULL;
}

void Dialog::delete_phrase(const QString &phrase_id)
{
    Phrase * phrase = findPhrase(phrase_id);
    if (phrase != NULL)
    {
		if (m_root == phrase)
		{
			m_root = NULL;
		}
        delete(phrase);
    }
}

void Dialog::toXML(const QString& file_name)
{
    QDomDocument doc ("ai_dialog");
    QDomElement root = doc.createElement( m_name );
    if (m_root != NULL)
    {
        root.setAttribute("root", m_root->getId());
    }
    doc.appendChild( root );

    QDomElement phrases = doc.createElement("phrases");
    QList<Phrase*> list = getAllPhrase();
    for (int i = 0; i < list.size(); i++)
    {
        phrases.appendChild(list[i]->toXML(doc));
    }
    root.appendChild(phrases);

    QFile  file(file_name);
    if( !file.open( QIODevice::WriteOnly ) )
    {
        // error
    }
    QTextStream ts( &file );
    ts.setCodec(QTextCodec::codecForName("UTF-8"));
    ts << doc.toString();
    file.close();
}

int Dialog::fromXML(const QString& file_name)
{
    QDomDocument doc( "IA_Model" );
    QFile file( file_name );
    if( !file.open( QIODevice::ReadOnly ) )
      return -1;
    if( !doc.setContent( &file ) )
    {
      file.close();
      return -2;
    }
    file.close();
    if (m_root != NULL)
    {
        delete(m_root);
    }
    QDomElement root = doc.documentElement();
    m_name =  root.tagName();
    QDomNode n = root.firstChild();
    QMap<QString, Phrase*> phrase_map;
    QMap<QString, QStringList> children;
    QMap<QString, QString> parents;
    while( !n.isNull() )
    {
        QDomElement e = n.toElement();
        QDomNode phrase_nod = e.firstChild();
        while (!phrase_nod.isNull())
        {
            QDomElement ele = phrase_nod.toElement();
            Phrase * phrase = new Phrase();
            phrase->fromXML(ele);
            children.insert(phrase->getId(),ele.attribute("children","").split(";"));
            parents.insert(phrase->getId(), ele.attribute("parent",""));
            phrase_map.insert(phrase->getId(), phrase);
            phrase_nod = phrase_nod.nextSibling();
        }
		n =n.nextSibling();
    }
    QMapIterator<QString, QStringList> it(children);
    while (it.hasNext())
    {
        it.next();
        QStringList phrase_children = it.value();
        for(int i = 0; i < phrase_children.size(); i++)
        {
            if (phrase_map.contains(phrase_children[i]))
            {
                phrase_map[it.key()]->addChild(phrase_map[phrase_children[i]]);
            }
        }
        if (phrase_map.contains(parents[it.key()]))
        {
            phrase_map[it.key()]->setParent(phrase_map[parents[it.key()]]);
        }
    }
    QString root_phrase = root.attribute("root","");
    if (phrase_map.contains(root_phrase))
    {
        m_root = phrase_map[root_phrase];
    }
    return 1;
}

Dialog& Dialog::operator =(const Dialog& dialog)
{
    m_name = dialog.m_name;
    if (m_root != NULL)
    {
        delete(m_root);
    }
    m_root = NULL;
    if (dialog.m_root != NULL)
    {
        Phrase * phrase = new Phrase(*dialog.m_root);
        m_root = phrase;
    }
    return *this;
}

}
